package com.orchard.orchardfarmmanagementsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.orchard.orchardfarmmanagementsystem.dto.*;
import com.orchard.orchardfarmmanagementsystem.entity.*;
import com.orchard.orchardfarmmanagementsystem.mapper.*;
import com.orchard.orchardfarmmanagementsystem.pojo.MaterialsQuantity;
import com.orchard.orchardfarmmanagementsystem.service.ITaskExecutorRelationService;
import com.orchard.orchardfarmmanagementsystem.service.ITaskOrchardRelationService;
import com.orchard.orchardfarmmanagementsystem.service.TaskService;
import com.orchard.orchardfarmmanagementsystem.service.UserService;
import com.orchard.orchardfarmmanagementsystem.utils.Result;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements TaskService {

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private SuppliesMapper suppliesMapper;

    @Autowired
    private TaskOrchardRelationMapper taskOrchardRelationMapper;

    @Autowired
    private TaskExecutorRelationMapper taskExecutorRelationMapper;

    @Autowired
    private TaskMaterialRelationMapper taskMaterialRelationMapper;

    @Autowired
    private InventoryMapper inventoryMapper; // 假设有一个库存服务

    @Autowired
    private ITaskOrchardRelationService taskOrchardRelationService;

    @Autowired
    private ITaskExecutorRelationService taskExecutorRelationService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private EvaluationMapper evaluationMapper; // 假设这是你用于访问评价表的Mapper

    @Override
    @Transactional
    public Result createTask(TaskDTO taskDTO) {
        // 验证开始日期是否大于结束日期
        if (taskDTO.getStartDate().after(taskDTO.getEndDate())) {
            return Result.error(50001,"开始日期不能晚于结束日期");
        }

        // 创建任务对象并设置默认值
        Task task = new Task();
        task.setTaskName(taskDTO.getName());
        task.setDescription(taskDTO.getDescription());
        task.setCreatedAt(new Date()); // 使用当前时间作为创建时间
        task.setDueDate(taskDTO.getEndDate()); // 设置截止日期为结束日期
        task.setStatus("进行中"); // 默认状态
        task.setPriority(1); // 默认优先级

        // 插入任务记录
        int taskId = taskMapper.insertTask(task);

        if (taskId <= 0) {
            return Result.error(50001, "任务创建失败");
        }

        // 更新关联表
        updateRelatedTables(task.getId(), taskDTO);

        return Result.success("任务创建成功");
    }

    @Override
    public List<TaskFetchDTO> getAllTasks(Map<String, String> queryParams) {
        // 执行连表查询
        List<Map<String, Object>> resultMap = taskMapper.selectTasksWithRelations(queryParams);

        // 将查询结果转换为DTO列表
        Map<Integer, TaskFetchDTO> taskMap = new HashMap<>();
        for (Map<String, Object> map : resultMap) {
            Integer taskId = (Integer) map.get("id");

            // 如果是新任务，则创建新的DTO对象
            if (!taskMap.containsKey(taskId)) {
                TaskFetchDTO dto = new TaskFetchDTO();
                dto.setId((Integer) map.get("id"));
                dto.setName((String) map.get("name"));
                dto.setDescription((String) map.get("description"));
                dto.setCreatedAt((LocalDateTime) map.get("created_at"));
                dto.setEndDate((LocalDateTime) map.get("end_date"));
                dto.setOrchardInfo((String) map.get("orchard_info"));
                dto.setMaterialsTools((String) map.get("materials_tools")); // 假设这个字段已经在查询中被正确拼接
                dto.setStatus((String) map.get("status"));
                dto.setAssignees(new ArrayList<>());

                taskMap.put(taskId, dto);
            }

            // 添加关联信息（负责人）
            TaskFetchDTO dto = taskMap.get(taskId);
            if (map.containsKey("assignee") && map.get("assignee") != null) {
                dto.getAssignees().add((String) map.get("assignee"));
            }
        }

        return new ArrayList<>(taskMap.values());
    }


    @Transactional
    public Result updateTaskStatus(Integer taskId, String statusValue) {
        try {
            // 根据ID查找任务
            Task task = taskMapper.selectById(taskId);
            if (task == null) {
                return Result.error(50001, "任务不存在");
            }

            // 检查当前状态是否为已完成或已取消
            if ("已完成".equals(task.getStatus()) || "已取消".equals(task.getStatus())) {
                return Result.error(50001, "任务状态为已完成或已取消，无法更改状态");
            }

            // 如果状态从其他状态变为已完成或已取消，则归还物资库存
            if (("已完成".equals(statusValue) || "已取消".equals(statusValue)) &&
                    !("已完成".equals(task.getStatus()) || "已取消".equals(task.getStatus()))) {
                try {
                    returnInventoryForTask(taskId); // 调用物资库存归还方法
                } catch (Exception e) {
                    log.error("归还物资库存时发生错误", e);
                    return Result.error(50001, "归还物资库存时发生错误：" + e.getMessage());
                }
            }

            // 更新任务状态
            task.setStatus(statusValue);

            // 更新任务记录
            int updated = taskMapper.updateById(task);
            if (updated <= 0) {
                return Result.error(50000, "更新任务状态失败");
            }

            return Result.success("任务状态更新成功");

        } catch (Exception e) {
            log.error("更新任务状态时发生错误", e); // 使用日志框架记录完整堆栈跟踪
            return Result.error(50000, "更新任务状态时发生错误：" + e.getMessage());
        }
    }

    /**
     * 获取已完成任务列表并填充评价信息
     *
     * @return 已完成任务的DTO列表
     */
    @Override
    public List<TaskEvaluationDTO> fetchCompletedTasks() {
        // 查询所有状态为“已完成”的任务，并关联评价信息
        List<Task> completedTasks = taskMapper.selectList(new QueryWrapper<Task>().eq("status", "已完成"));

        // 批量获取所有相关评价信息
        Map<Integer, Evaluation> evaluationsByTaskId = getSingleEvaluationForTasks(completedTasks);

        return completedTasks.stream()
                .map(task -> {
                    TaskEvaluationDTO dto = new TaskEvaluationDTO();
                    BeanUtils.copyProperties(task, dto);
                    dto.setName(task.getTaskName());
                    dto.setStartDate(task.getCreatedAt());
                    dto.setEndDate(task.getDueDate());

                    // 设置负责人
                    String assignee = getAssigneesForTask(task.getId());
                    dto.setAssignee(assignee);

                    // 设置评价信息
                    Evaluation evaluation = evaluationsByTaskId.get(task.getId());
                    if (evaluation != null) {
                        dto.setRating(evaluation.getRating());
                        dto.setComment(evaluation.getComment());
                        dto.setEvaluator(getUsernameById(evaluation.getUserId()));
                    }

                    return dto;
                })
                .collect(Collectors.toList());
    }

    /**
     * 根据任务ID批量获取唯一的评价信息
     *
     * @param tasks 任务列表
     * @return 每个任务对应的唯一评价信息映射
     */
    private Map<Integer, Evaluation> getSingleEvaluationForTasks(List<Task> tasks) {
        List<Integer> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
        return evaluationMapper.selectList(new QueryWrapper<Evaluation>().in("task_id", taskIds))
                .stream()
                .collect(Collectors.toMap(Evaluation::getTaskId, evaluation -> evaluation, (existing, replacement) -> existing));
    }

    /**
     * 根据用户ID获取用户名
     *
     * @param userId 用户ID
     * @return 用户名
     */
    private String getUsernameById(Integer userId) {
        User user = userMapper.selectById(userId);
        return user != null ? user.getUsername() : "未知用户";
    }

    /**
     * 查询用户与任务的关联表并设置负责人
     *
     * @param taskId 任务ID
     * @return 负责人字符串
     */
    private String getAssigneesForTask(Integer taskId) {
        // 使用stream API来构建负责人字符串
        return taskExecutorRelationMapper.selectList(new QueryWrapper<TaskExecutorRelation>().eq("task_id", taskId))
                .stream()
                .map(relation -> userMapper.selectById(relation.getUserId()).getUsername())
                .collect(Collectors.joining(", "));
    }


    public void returnInventoryForTask(Integer taskId) throws Exception {
        // 根据任务ID获取所需归还的物资信息
        List<TaskMaterialRelation> materials = taskMaterialRelationMapper.getMaterialsByTaskId(taskId);

        for (TaskMaterialRelation material : materials) {
            // 获取物资类型
            Materials m = suppliesMapper.selectById(material.getMaterialId());
            if ("tool".equalsIgnoreCase(m.getType())) { // 只对类型为 tool 的物资进行库存归还
                // 归还库存逻辑
                int updatedRows = inventoryMapper.returnInventory(material.getMaterialId(), material.getRequiredQuantity());
                if (updatedRows <= 0) {
                    throw new RuntimeException("无法更新库存，材料ID: " + material.getMaterialId());
                }
            }
        }
    }


    @Transactional
    public void updateRelatedTables(Integer taskId, TaskDTO taskDTO) {
        // 构建果园关联关系列表并批量插入
        List<TaskOrchardRelation> orchardRelations = taskDTO.getOrchardIds().stream()
                .map(orchardId -> {
                    TaskOrchardRelation relation = new TaskOrchardRelation();
                    relation.setTaskId(taskId);
                    relation.setOrchardId(orchardId);
                    return relation;
                })
                .collect(Collectors.toList());

        if (!orchardRelations.isEmpty()) {
            taskOrchardRelationService.saveBatch(orchardRelations);
        }

        // 构建执行人员关联关系列表并批量插入
        LocalDateTime now = LocalDateTime.now();
        String status = TaskStatus.ASSIGNED.getValue();

        List<TaskExecutorRelation> executorRelations = taskDTO.getExecutorIds().stream()
                .map(executorId -> {
                    TaskExecutorRelation relation = new TaskExecutorRelation();
                    relation.setTaskId(taskId);
                    relation.setUserId(executorId);
                    relation.setAssignedAt(now);
                    relation.setStatus(status);
                    return relation;
                })
                .collect(Collectors.toList());

        if (!executorRelations.isEmpty()) {
            taskExecutorRelationService.saveBatch(executorRelations);
        }

        // 更新物资关联表并扣减库存
        for (MaterialsQuantity materialQuantity : taskDTO.getMaterials()) {
            MaterialDTO materialDTO = materialQuantity.getMaterial();
            Integer requiredQuantity = materialQuantity.getRequiredQuantity();

            taskMaterialRelationMapper.insertTaskMaterialRelation(taskId, materialDTO.getId(), requiredQuantity);
// 扣减库存
            int rowsAffected = inventoryMapper.deductInventory(materialDTO.getId(), requiredQuantity);
            if (rowsAffected == 0) {
                throw new RuntimeException("库存不足，无法完成任务创建");
            }
        }
    }
}

